/**
 * @author QL
 * @date 2022-02-28 14:57:04
 * @version V..
 * @description 根据baseMap对象二次包的api，实现一些综合性的业务功能方法的类
 */
import MapClass from './baseMap_class';
import { DoubleClickZoom } from "ol/interaction";
import { Style, Icon } from 'ol/style'

class MapBusiness extends MapClass {
    /**
    * @author QL
    * @functionName constructor
    * @param { Object } con 父类初始化底图对象的配置对象
    * @param { String } containerId 父类初始化底图的DOM容器Id属性值
    * @date 2022-02-21 14:59:30
    * @version V..
    * @description 类构造方法
    */
    constructor(con, containerId) {
        // 初始化父类构造器以初始化父类继承的属性
        super(con, containerId);

        // 图层对象的缓存
        this.layers = {};

        // 鼠标悬停的要素缓存对象
        this.hoverFeature = {};

        // 事件对象的缓存
        this.selfEvents = {
            singleclick: [],
            pointermove: [],
            moveend: [],
        };
    }

    /**
     * @author QL
     * @functionName initEvents
     * @param { * }  
     * @date 2022-03-02 16:43:39
     * @version V..
     * @description 初始化地图监听事件, 绑定自定义事件监听缓存
     */
    initEvents() {
        // 禁用鼠标双击缩放事件
        let dblClickInteraction = this.baseMap
            .getInteractions()
            .getArray()
            .find(interaction => {
                return interaction instanceof DoubleClickZoom;
            });
        this.baseMap.removeInteraction(dblClickInteraction);

        // 初始化鼠标悬停变更要素样式的事件
        let featureHover = {
            eventName: "featureHover",
            type: "pointermove",
            fn: this.featureHover,
        }
        this.selfEvents.pointermove.push(featureHover);

        // 初始化鼠标悬停变更要素样式的事件
        let featureClick = {
            eventName: "featureClick",
            type: "singleclick",
            fn: this.featureClick,
        }
        this.selfEvents.singleclick.push(featureClick);

        // 开启鼠标单击事件的监听
        this.baseMap.on("singleclick", evt => {
            console.log("鼠标单机事件：", evt);
            this.selfEvents.singleclick.forEach(selfEvent => {
                if (typeof selfEvent.fn == "function") {
                    selfEvent.fn(this.baseMap, evt);
                }
            })
        });

        // 开启鼠标移动事件的监听
        this.baseMap.on("pointermove", evt => {
            // console.log("鼠标移动事件：",evt);
            this.selfEvents.pointermove.forEach(selfEvent => {
                if (typeof selfEvent.fn == "function") {
                    selfEvent.fn(this.baseMap, evt);
                }
            })
        });

        // 开启底图拖动事件的监听
        this.baseMap.on("moveend", evt => {
            console.log("底图拖动事件：", evt);
            this.selfEvents.moveend.forEach(selfEvent => {
                if (typeof selfEvent.fn == "function") {
                    selfEvent.fn(this.baseMap, evt);
                }
            })
        });
    }

    /**
     * @author QL
     * @functionName sprinkle
     * @param { Array } ponitList 
     * @param { String } layerId 
     * @date 2022-02-28 14:58:13
     * @version V..
     * @description 撒点业务方法
     */
    sprinkle(ponitList, layerId, fn) {
        try {
            let layerIds = Object.keys(this.layers);
            let layerIndex = layerIds.indexOf(layerId)
            if (layerIndex == -1) {
                let features = this.instantiatedFeatures(ponitList);
                let vectorLayer = this.instantiatedVectorLayer(features);
                this.baseMap.addLayer(vectorLayer);
                this.layers[layerId] = vectorLayer;
                return fn("checked");
            } else {
                this.layers[layerIds[layerIndex]].getSource().clear();
                this.baseMap.removeLayer(this.layers[layerIds[layerIndex]]);
                delete this.layers[layerIds[layerIndex]];
                return fn("unChecked");
            }
        } catch (e) {
            return fn(e);
        }
    }

    /**
     * @author QL
     * @functionName bindSelfEvent
     * @param { Object } selfEvent 
     * @date 2022-03-03 11:21:24
     * @version V..
     * @description 添加新的自定义监听事件
     */
    bindSelfEvent(selfEvent = {
        eventName: "",
        eventType: "",
        fn: (evt) => { console.log("事件绑定默认值测试") }
    }) {
        this.selfEvents[selfEvent.eventType].push(selfEvent);
    }

    /**
     * @author QL
     * @functionName unboundSelfEvent
     * @param { Object } selfEvent 
     * @date 2022-03-03 11:21:58
     * @version V..
     * @description 删除自定义监听事件
     */
    unboundSelfEvent(selfEvent) {
        let eventIndex = this.selfEvents[selfEvent.eventType].indexOf(selfEvent);
        this.selfEvents[selfEvent.eventType].splice(eventIndex, 1);
    }

    /**
     * @author QL
     * @date 2022-03-04 10:44:11
     * @version V..
     * @description 用作监听事件绑定的自定义方法
     */
    /**
     * @author QL
     * @functionName featureHover
     * @param { Object } baseMap 基础底图实例对象 
     * @param { Object } evt 监听事件的回调值
     * @date 2022-03-03 16:33:27
     * @version V..
     * @description 采用ol/Map 的forEachFeatureAtPixel 方法获取点击位置的要素,通过 hasFeatureAtPixel 方法判断鼠标移动是否触及要素，以更改和还原要素样式
     */
    featureHover(baseMap, evt) {
        try {
            if (baseMap.hasFeatureAtPixel(evt.pixel)) {
                baseMap.forEachFeatureAtPixel(evt.pixel, (feature, layer) => {
                    if (!feature.getProperties().checked) {
                        this.hoverFeature = feature;
                        // 设置要素的样式
                        feature.setStyle([
                            new Style({
                                image: new Icon({
                                    anchor: [0.5, 1],// 显示位置
                                    size: [48, 48],// 尺寸
                                    imageSize: [48, 48],// 尺寸
                                    src: require('./assets/thumbtack_hover.png')// 图片url
                                })
                            })
                        ])
                    }
                });
            } else {
                if (!this.hoverFeature.getProperties().checked) {
                    this.hoverFeature.setStyle([
                        new Style({
                            image: new Icon({
                                anchor: [0.5, 1],// 显示位置
                                size: [32, 32],// 尺寸
                                imageSize: [32, 32],// 尺寸
                                src: require('./assets/thumbtack.png')// 图片url
                            })
                        })
                    ])
                    this.hoverFeature = {};
                }
            }
        } catch (e) {
            // console.log("异常：", e)
        }
    }
    /**
     * @author QL
     * @functionName featureClick
     * @param { Object } baseMap 基础底图实例对象 
     * @param { Object } evt 监听事件的回调值
     * @date 2022-03-03 16:33:27
     * @version V..
     * @description 采用ol/Map 的forEachFeatureAtPixel 方法获取点击位置的要素,通过 hasFeatureAtPixel 方法判断鼠标点击是否触及要素，以更改和还原要素样式
     */
    featureClick(baseMap, evt) {
        try {
            baseMap.forEachFeatureAtPixel(evt.pixel, (feature, layer) => {
                if (feature.getProperties().checked) {
                    feature.setProperties({ checked: false });
                    // 设置要素的样式
                    feature.setStyle([
                        new Style({
                            image: new Icon({
                                anchor: [0.5, 1],// 显示位置
                                size: [48, 48],// 尺寸
                                imageSize: [48, 48],// 尺寸
                                src: require('./assets/thumbtack_hover.png')// 图片url
                            })
                        })
                    ])
                } else {
                    feature.setProperties({ checked: true });
                    // 设置要素的样式
                    feature.setStyle([
                        new Style({
                            image: new Icon({
                                anchor: [0.5, 1],// 显示位置
                                size: [48, 48],// 尺寸
                                imageSize: [48, 48],// 尺寸
                                src: require('./assets/thumbtack_checked.png')// 图片url
                            })
                        })
                    ])
                }
                console.log("feature.getProperties():", feature.getProperties());
            });
        } catch (e) {
            console.log("异常：", e)
        }
    }

    /**
     * @author QL
     * @date 2022-03-02 09:46:41
     * @version V..
     * @description getters
     */
    _getLayers() {
        return this.layers;
    }
    _getSelfEvents(eventType) {
        return this.selfEvents[eventType];
    }
}

export default MapBusiness;